package com.yjyw.tiexie.common.permission;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;

import com.yjyw.tiexie.js.IFunction;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by SmallYou on 2018/12/3 0003.
 * DESC:TODO()
 */

public class PermissionManager {
    /**
     * 检查有没有权限
     *
     * @param activity
     * @param perms
     * @return
     */
    public static boolean hasPermissions(@NonNull Activity activity, @NonNull String... perms) {
        //使用@NonNull 以下两行代码可省略
//        if (activity != null) {
//            throw new IllegalArgumentException("activity不能为空");
//        }
        //如果低于6.0无需做判断
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true;
        }
        for (String item : perms) {
            //任何一个权限拒绝就return false
            if (ContextCompat.checkSelfPermission(activity, item) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }

    /**
     * 申请权限
     *
     * @param activity
     * @param requestCode
     * @param perms
     */
    public static void requestPermissions(@NonNull Activity activity, int requestCode, @NonNull String... perms) {
        //申请权限之前做一次检查，避免其他人使用时不做权限检查
        if (hasPermissions(activity, perms)) {//已有全部权限
            notifyHasPermissions(activity, requestCode, perms);
        } else {
            //permission helper
            PermissionHelper helper = PermissionHelper.newInstance(activity);
            helper.requestPermissions(requestCode, perms);
        }
    }

    /**
     * 如果全部被授权则进入onRequestPermissionsResult方法返回结果
     *
     * @param activity
     * @param requestCode
     * @param perms
     */
    private static void notifyHasPermissions(Activity activity, int requestCode, String[] perms) {
        int[] grantResults = new int[perms.length];
        for (int i = 0; i < perms.length; i++) {
            grantResults[i] = PackageManager.PERMISSION_GRANTED;//全部通过
        }
        onRequestPermissionsResult(requestCode, perms, grantResults, activity);
    }


    /**
     * 处理权限请求结果方法
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     * @param activity
     */
    public static void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults, Activity activity) {

        //授权的集合
        List<String> grant = new ArrayList<>();
        //未授权的集合
        List<String> denied = new ArrayList<>();

        for (int i = 0; i < permissions.length; i++) {
            if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                grant.add(permissions[i]);
            } else {
                denied.add(permissions[i]);
            }
        }
        //授权回调activity
        if (!grant.isEmpty()) {
            if (activity instanceof PermissionCallback) {
                ((PermissionCallback) activity).onPermissionGranted(requestCode, grant);
            }
        }
        //未授回调activity
        if (!denied.isEmpty()) {
            if (activity instanceof PermissionCallback) {
                ((PermissionCallback) activity).onPermissionDenied(requestCode, denied);
            }
        }

        //授权全部通过
        if (!grant.isEmpty() && denied.isEmpty()) {
            reflectAnnotationMethod(activity, requestCode);
        }

    }

    /**
     * 找到指定activity中有IPermission注解和对应请求requestCode参数的方法，并执行
     *
     * @param activity
     * @param requestCode
     */
    private static void reflectAnnotationMethod(Activity activity, int requestCode) {
        //获取类
        Class<? extends Activity> aClass = activity.getClass();
        //获取方法
        Method[] declaredMethods = aClass.getDeclaredMethods();
//        //其它场景性能优化：N个父类不可能有自定义注解，排出后再反射
//        //找出系统类直接跳出 while break
//        String clazzName = aClass.getName();
//        if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") || clazzName.startsWith("android.")) {
//        }
        //遍历所有方法
        for (Method method : declaredMethods) {
            //如果方法时IPermission注解
            if (method.isAnnotationPresent(IPermission.class)) {
                IPermission iPermission = method.getAnnotation(IPermission.class);
                //对应请求requestCode
                if (iPermission.value() == requestCode) {
                    //严格校验
                    //如果方法返回类型为void
                    Type type = method.getGenericReturnType();
                    if (!"void".equals(type.toString())) {
                        throw new RuntimeException("方法必须是void");
                    }
                    //方法参数
                    Class<?>[] parameterTypes = method.getParameterTypes();
                    if (parameterTypes.length > 0) {
                        throw new RuntimeException("方法必须是无参数");
                    }
                    try {
                        //当方法为私有设置可访问
                        if (!method.isAccessible()) method.setAccessible(true);
                        //执行方法
                        method.invoke(activity);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 找到指定activity中有IPermission注解和对应请求requestCode参数的方法，并执行
     *
     * @param activity
     * @param requestCode
     */
    public static void inflate(Activity activity, int requestCode) {
        //获取类
        Class<? extends Activity> aClass = activity.getClass();
        //获取方法
        Method[] declaredMethods = aClass.getDeclaredMethods();

        //遍历所有方法
        for (Method method : declaredMethods) {
            //如果方法时IPermission注解
            if (method.isAnnotationPresent(IFunction.class)) {
                IFunction iPermission = method.getAnnotation(IFunction.class);
                //对应请求requestCode
                if (iPermission.value() == requestCode) {
                    //严格校验
                    //如果方法返回类型为void
                    Type type = method.getGenericReturnType();
                    if (!"void".equals(type.toString())) {
                        throw new RuntimeException("方法必须是void");
                    }
                    //方法参数
                    Class<?>[] parameterTypes = method.getParameterTypes();
//                    if (parameterTypes.length > 0) {
//                        throw new RuntimeException("方法必须是无参数");
//                    }
                    try {
                        //当方法为私有设置可访问
                        if (!method.isAccessible()) method.setAccessible(true);
                        //执行方法
                        method.invoke(activity);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }


    /**
     * 拒绝权限集合中是否点击了不再询问
     *
     * @param activity
     * @param denied
     * @return
     */
    public static boolean somePermissionNotAskAgain(Activity activity, List<String> denied) {
        PermissionHelper helper = PermissionHelper.newInstance(activity);
        return helper.somePermissionNotAskAgain(denied);
    }
}
